#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "hi_wifi_api.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "MQTTClient.h"

static MQTTClient mq_client;

unsigned char *onenet_mqtt_buf;
unsigned char *onenet_mqtt_readbuf;
int buf_size;

Network n;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;  

// 全局变量：存储从name主题接收到的消息
int g_mqtt_command = 0;  // 默认值为0，表示没有接收到有效命令
//全局变量 ：存储从speed主题接收到的速度
int g_mqtt_speed=0;
// 获取MQTT命令的函数（供其他程序调用）
int get_mqtt_command(void)
{
    return g_mqtt_command;
}
//获取速度的函数
int get_mqtt_speed(void)
{
    return g_mqtt_speed;
}

// 重置MQTT命令的函数（可选）
void reset_mqtt_command(void)
{
    g_mqtt_command = 0;
}

// 设置MQTT命令的函数（可选，用于测试）
void set_mqtt_command(int command)
{
    if (command >= 1 && command <= 5) {
        g_mqtt_command = command;
        printf("MQTT command manually set to: %d\n", command);
    }
}

//消息回调函数
void mqtt_callback(MessageData *msg_data)
{
    size_t res_len = 0;
    uint8_t *response_buf = NULL;
    char topicname[45] = { "$crsp/" };

    LOS_ASSERT(msg_data);

    // 提取主题名称
    char topic[50] = {0};
    if (msg_data->topicName->lenstring.len < sizeof(topic)) {
        memcpy(topic, msg_data->topicName->lenstring.data, msg_data->topicName->lenstring.len);
        topic[msg_data->topicName->lenstring.len] = '\0';
    }

    // 提取消息内容
    char message[50] = {0};
    if (msg_data->message->payloadlen < sizeof(message)) {
        memcpy(message, msg_data->message->payload, msg_data->message->payloadlen);
        message[msg_data->message->payloadlen] = '\0';
    }

    printf("topic %s receive a message\r\n", topic);
    printf("message is %s\r\n", message);

    // 如果是name主题，解析消息并更新全局变量
    if (strcmp(topic, "name") == 0) {
        parse_name_message(message);
    }
    // 如果是speed主题，解析速度消息
    else if (strcmp(topic, "speed") == 0) {
        parse_speed_message(message);
    }
}

// 解析name主题的消息
void parse_name_message(const char* message)
{
    printf("Parsing name message: %s\n", message);
    
    // 将字符串转换为整数
    int command = atoi(message);
    
    // 验证命令是否在有效范围内（1-5）
    if (command >= 1 && command <= 5) {
        g_mqtt_command = command;
        printf("✅ Valid MQTT command received: %d\n", g_mqtt_command);
        
        // 可选：根据命令值执行相应操作
        switch (g_mqtt_command) {
            case 1:
                printf("📝 Command 1: Action 前进\n");
                break;
            case 2:
                printf("📝 Command 2: Action 后退\n");
                break;
            case 3:
                printf("📝 Command 3: Action 左转\n");
                break;
            case 4:
                printf("📝 Command 4: Action 右转\n");
                break;
            case 5:
                printf("📝 Command 5: Action 停止\n");
                break;
        }
    } else {
        printf("❌ Invalid MQTT command: %s (expected 1-5)\n", message);
        g_mqtt_command = 0;  // 设置为0表示无效命令
    }
}
void parse_speed_message(const char* message)
{
    printf("Parsing speed message: %s\n", message);
    
    // 将字符串转换为整数
    int speed = atoi(message);
    
    // 验证速度是否在有效范围内（0-100）
    if (speed >= 0 && speed <= 100) {
        g_mqtt_speed = speed;
        printf("✅ Valid MQTT speed received: %d\n", g_mqtt_speed);
        
        // 可选：根据速度值执行相应操作
        if (speed == 0) {
            printf("🛑 Speed 0: Motor stopped\n");
        } else if (speed <= 25) {
            printf("🐌 Speed %d: Low speed\n", speed);
        } else if (speed <= 50) {
            printf("🚗 Speed %d: Medium speed\n", speed);
        } else if (speed <= 75) {
            printf("🏃 Speed %d: High speed\n", speed);
        } else {
            printf("🚀 Speed %d: Maximum speed\n", speed);
        }
    } else {
        printf("❌ Invalid MQTT speed: %s (expected 0-100)\n", message);
        g_mqtt_speed = 0;  // 设置为0表示无效速度
    }
}
int mqtt_connect(void)
{
    int rc = 0;
    
    NetworkInit(&n);
    // NetworkConnect(&n, "172.20.10.10", 1883); //IP of cjy
    NetworkConnect(&n, "192.168.89.53", 1883);  //IP of wly

    buf_size  = 4096+1024;
    onenet_mqtt_buf = (unsigned char *) malloc(buf_size);
    onenet_mqtt_readbuf = (unsigned char *) malloc(buf_size);
    if (!(onenet_mqtt_buf && onenet_mqtt_readbuf))
    {
        printf("No memory for MQTT client buffer!");
        return -2;
    }

    MQTTClientInit(&mq_client, &n, 1000, onenet_mqtt_buf, buf_size, onenet_mqtt_readbuf, buf_size);
    
    MQTTStartTask(&mq_client);

    data.keepAliveInterval = 30;
    data.cleansession = 1;
    data.clientID.cstring = "ohos_hi3861";
    // data.username.cstring = "admin";  //MQTT username of cjy
    data.username.cstring = "admin";  //MQTT username of wly
    // data.password.cstring = "12345678";  //MQTT password of cjy
    data.password.cstring = "wly";  //MQTT password of wly
    data.cleansession = 1;
    
    mq_client.defaultMessageHandler = mqtt_callback;

    //连接服务器
    rc = MQTTConnect(&mq_client, &data);
    
    if (rc != 0) {
        printf("MQTT Connect failed, return code: %d\n", rc);
        return rc;
    }

    printf("MQTT Connected successfully!\n");

    //订阅消息，并设置回调函数
    MQTTSubscribe(&mq_client, "name", 0, mqtt_callback);
    MQTTSubscribe(&mq_client, "speed", 0, mqtt_callback);
    printf("Subscribed to 'name' and 'speed' topics successfully!\n");

    int count = 0;
    while(1)
    {
        MQTTMessage message;
        char payload[80];
        
        // 发送心跳消息，包含当前命令状态和速度
        sprintf(payload, "heartbeat_%d_cmd_%d_speed_%d", count++, g_mqtt_command, g_mqtt_speed);

        message.qos = QOS1;
        message.retained = 0;
        message.payload = (void *)payload;
        message.payloadlen = strlen(payload);

        //发送消息
        if (MQTTPublish(&mq_client, "ID", &message) < 0)
        {
            printf("MQTTPublish failed!\r\n");
        }
        else
        {
            printf("Published: %s (cmd: %d, speed: %d)\r\n", payload, g_mqtt_command, g_mqtt_speed);
        }
        
        usleep(1000000);  // 1秒发送一次
    }


    return 0;
}

void mqtt_test(void)
{
    mqtt_connect();
}